import uvicorn as uvicorn
from fastapi import FastAPI
from fastapi.openapi.docs import get_swagger_ui_html
from pymysql import OperationalError
from sqlalchemy.exc import IntegrityError, StatementError,InvalidRequestError
from starlette.middleware.cors import CORSMiddleware
from starlette.requests import Request
from starlette.responses import RedirectResponse
from starlette.staticfiles import StaticFiles
import time
from api import api_router
from config import allow_origins, allow_methods, allow_headers, ROUTER_PREFIX
# from middleware import TokenVerifyMiddleware
# from middleware.exception_middleware import ExceptionHandlerMiddleware
from middleware import TokenVerifyMiddleware
from middleware.database_middleware import DatabaseHandlerMiddleware
from middleware.exception_middleware import ExceptionHandlerMiddleware
from model.db import mysql_init
from model.redis import redis_init
from util import IntegrityExceptionHandler, DataNotExist
from util.exception_handlers import DataNotExistExceptionHandler, AllException, AllExceptionHandler, \
    PwdNotMateExceptionHandler, PwdNotMate, LoginCodeException, LoginCodeExceptionHandler, \
    StatementErrorExceptionHandler, DataNotDeleteExceptionHandler, DataNotDelete, UserNotActivated, \
    UserNotActivatedExceptionHandler, UserNoPermissionExceptionHandler, UserNoPermission, \
    OperationalErrorExceptionHandler, InvalidRequestErrorExceptionHandler
from fastapi import applications

from util.timedTask import scheduler

"""
解决swagger外网无法访问
"""


def swagger_monkey_patch(*args, **kwargs):
    """
    Wrap the function which is generating the HTML for the /docs endpoint and
    overwrite the default values for the swagger js and css.
    """
    return get_swagger_ui_html(
        *args, **kwargs,
        swagger_js_url="https://cdn.staticfile.org/swagger-ui/4.15.5/swagger-ui-bundle.min.js",
        swagger_css_url="https://cdn.staticfile.org/swagger-ui/4.15.5/swagger-ui.min.css")


applications.get_swagger_ui_html = swagger_monkey_patch

app = FastAPI()
"""
配置CORS
"""
app.add_middleware(
    CORSMiddleware,
    allow_origins=allow_origins,
    allow_credentials=False,
    allow_methods=allow_methods,
    allow_headers=allow_headers
)
"""
注册路由
"""
app.include_router(api_router)
# 静态资源访问
app.mount(f'{ROUTER_PREFIX}/public', StaticFiles(directory="public"), name="静态资源")
# app.mount('/public', StaticFiles(directory="public"), name="静态资源")

"""
注册中间件
"""
app.middleware('http')(TokenVerifyMiddleware())  # token校验中间件
app.middleware('http')(ExceptionHandlerMiddleware())  # 异常校验中间件
app.middleware('http')(DatabaseHandlerMiddleware())

"""
初始化数据库
"""
redis_init(app)
mysql_init(app)

"""
注册异常处理，智能处理HTTP请求异常
# """
# 唯一索引异常处理
app.add_exception_handler(IntegrityError, IntegrityExceptionHandler())

# 数据不可删除
app.add_exception_handler(DataNotDelete, DataNotDeleteExceptionHandler())
# 数据库异常
app.add_exception_handler(StatementError, StatementErrorExceptionHandler())
app.add_exception_handler(OperationalError, OperationalErrorExceptionHandler())
app.add_exception_handler(InvalidRequestError, InvalidRequestErrorExceptionHandler())
# 数据不存在
app.add_exception_handler(DataNotExist, DataNotExistExceptionHandler())
# 登录验证码错误
app.add_exception_handler(LoginCodeException, LoginCodeExceptionHandler())
# 密码错误
app.add_exception_handler(PwdNotMate, PwdNotMateExceptionHandler())
# # 用户未激活
app.add_exception_handler(UserNotActivated, UserNotActivatedExceptionHandler())
# # 用户无权限
app.add_exception_handler(UserNoPermission, UserNoPermissionExceptionHandler())
# 全局异常处理
app.add_exception_handler(AllException, AllExceptionHandler())





@app.on_event("shutdown")
def shutdown_event():
    # 当 FastAPI 应用关闭时，关闭定时任务
    scheduler.shutdown()


@app.get("/")
async def root(request: Request):
    current_ip = request.scope["server"][0]
    # 重定向到接口文档
    return RedirectResponse(f"http://{current_ip}:8085/docs")

project_id = 0


if __name__ == "__main__":
    uvicorn.run(app='main:app', host="0.0.0.0", port=8085, reload=False)
